<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>判断变量的类型的方法</title>
</head>

<body>

</body>
<script>
  "use strict"; {
    /* typeof 返回一个表示数据类型的字符串，返回结果包括：number、boolean、string、object、undefined、function等6种数据类型。如果是判断一个基本的类型用typeof就是可以的。 */
    typeof ''; // string 有效
    typeof 1; // number 有效
    typeof true; //boolean 有效
    typeof undefined; //undefined 有效
    typeof null; //object 无效
    typeof []; //object 无效
    typeof new Function(); // function 有效
    typeof new Date(); //object 无效
    typeof new RegExp(); //object 无效
  }; {
    /* instanceof 是用来判断 A 是否为 B 的实例对，表达式为：A instanceof B，如果A是B的实例，则返回true, 否则返回false。在这里需要特别注意的是：instanceof检测的是原型*/

    [] instanceof Array; //true
    // { } instanceof Object; //true
    new Date() instanceof Date; //true
  }; {
    /* 
      每一个对象实例都可以通过 constrcutor 对象来访问它的构造函数 。JS 中内置了一些构造函数：Object、Array、Function、Date、RegExp、String等。我们可以通过数据的 constrcutor 是否与其构造函数相等来判断数据的类型。
        不能判断 undefined 和 null
    */
    var arr = [];
    var obj = {};
    var date = new Date();
    var num = 110;
    var str = 'Hello';
    var getName = function () { };
    var sym = Symbol();
    var set = new Set();
    var map = new Map();
    arr.constructor === Array; // true
    obj.constructor === Object; // true
    date.constructor === Date; // true
    str.constructor === String; // true
    getName.constructor === Function; // true
    sym.constructor === Symbol; // true
    set.constructor === Set; // true
    map.constructor === Map // true
  }; {
    /* 
      toString是Object原型对象上的一个方法，该方法默认返回其调用者的具体类型，更严格的讲，是 toString运行时this指向的对象类型, 返回的类型格式为[object, xxx], xxx是具体的数据类型，其中包括：String, Number, Boolean, Undefined, Null, Function, Date, Array, RegExp, Error, HTMLDocument, ... 基本上所有对象的类型都可以通过这个方法获取到。
    */

    Object.prototype.toString.call(''); // [object String]
    Object.prototype.toString.call(1); // [object Number]
    Object.prototype.toString.call(true); // [object Boolean]
    Object.prototype.toString.call(undefined); // [object Undefined]
    Object.prototype.toString.call(null); // [object Null]
    Object.prototype.toString.call(new Function()); // [object Function]
    Object.prototype.toString.call(new Date()); // [object Date]
    Object.prototype.toString.call([]); // [object Array]
    Object.prototype.toString.call(new RegExp()); // [object RegExp]
    Object.prototype.toString.call(new Error()); // [object Error]
  }; {
    // 自己封装数据类型的检测
    /**
    * @description: 数据类型的检测
    * @param {any} data 要检测数据类型的变量
    * @return {string} type 返回具体的类型名称【小写】
    */
    const isTypeOf = data => {
      return Object.prototype.toString.call(data).replace(/\[object (\w+)\]/, '$1').toLowerCase()
    }
    console.log(isTypeOf({})) // object
    console.log(isTypeOf([])) // array
    console.log(isTypeOf("ss")) // string
    console.log(isTypeOf(1)) // number
    console.log(isTypeOf(false)) // boolean
    console.log(isTypeOf(new RegExp())) // regexp
    console.log(isTypeOf(/w+/)) // regexp
    console.log(isTypeOf(null)) // null
    console.log(isTypeOf(undefined)) // undefined
    console.log(isTypeOf(Symbol("id"))) // symbol
    console.log(isTypeOf(() => { })) // function
  }
</script>

</html>